package system

import (
	"fmt"
	"strings"

	"quickK8s/config"
	"quickK8s/pkg/utils"
)

// Manager 系统配置管理结构体
type Manager struct {
	cfg      *config.ClusterConfig
	executor utils.CommandExecutor
}

// NewManager 创建系统配置管理器实例
func NewManager(cfg *config.ClusterConfig, executor utils.CommandExecutor) *Manager {
	return &Manager{
		cfg:      cfg,
		executor: executor,
	}
}

// SetupHostsOnAllNodes 配置所有节点的hosts文件和主机名
func (m *Manager) SetupHostsOnAllNodes() error {
	// 准备 hosts 内容和主机名映射
	var entries []string
	var hostnameCommands []string

	// 配置 master 节点
	for i, master := range m.cfg.Cluster.Masters {
		hostname := fmt.Sprintf("master%02d", i+1)
		entries = append(entries, fmt.Sprintf("\"%s %s\"", master, hostname))
		hostnameCommands = append(hostnameCommands,
			fmt.Sprintf("echo %s > /etc/hostname && hostname %s", hostname, hostname))
	}

	// 配置 worker 节点
	for i, node := range m.cfg.Cluster.Nodes {
		hostname := fmt.Sprintf("node%02d", i+1)
		entries = append(entries, fmt.Sprintf("\"%s %s\"", node, hostname))
		hostnameCommands = append(hostnameCommands,
			fmt.Sprintf("echo %s > /etc/hostname && hostname %s", hostname, hostname))
	}

	// 构建检查和更新hosts的命令
	checkAndUpdateHosts := fmt.Sprintf(`
for entry in %s; do
    if ! grep -q "${entry}" /etc/hosts; then
        echo "${entry}" >> /etc/hosts
        echo "添加 hosts 条目: ${entry}"
    else
        echo "hosts 条目已存在: ${entry}"
    fi
done
`, strings.Join(entries, " "))

	// 构建完整的命令，包括设置主机名
	fullCommand := fmt.Sprintf(`
# 设置主机名
IP=$(hostname -I | awk '{print $1}')
%s

# 更新 hosts 文件
%s

# 应用主机名更改
systemctl restart systemd-hostnamed

echo "主机名和hosts配置完成"
`, strings.Join(hostnameCommands, "\n"), checkAndUpdateHosts)

	// 在所有节点上执行命令
	return m.executeOnAllNodes(fullCommand)
}

// executeOnAllNodes 在所有节点上执行命令
func (m *Manager) executeOnAllNodes(command string) error {
	allNodes := append(m.cfg.Cluster.Masters, m.cfg.Cluster.Nodes...)

	// 在每个节点上执行命令
	for _, node := range allNodes {
		if err := m.executor.RunCommand("sshpass", "-p", m.cfg.Cluster.Password,
			"ssh", "-o", "StrictHostKeyChecking=no",
			fmt.Sprintf("root@%s", node), command); err != nil {
			return fmt.Errorf("在节点 %s 执行命令失败: %v", node, err)
		}
	}
	return nil
}
